#include <regx52.h>
#include <intrins.h>
#include "delay.h"

#define DS18B20_OW   P3_7

void ds18b20_write_bit(unsigned char b) 
{
	if(b&0x01) 
	{
		DS18B20_OW = 0;//拉低总线
		_nop_();_nop_();//2us
		DS18B20_OW = 1;//写1
		delay(6);//60us
	} else {
		DS18B20_OW = 0;//拉低总线
		delay(6);//60us
		DS18B20_OW = 1;//释放总线
		_nop_();_nop_();//2us
	}
}

unsigned char ds18b20_read_bit() 
{
	DS18B20_OW = 0;//拉低总线
	_nop_();_nop_();//2us
	DS18B20_OW = 1;//释放总线
	_nop_();_nop_();//等待18b20将数据送到总线
	if(DS18B20_OW) 
	{
		_nop_();_nop_();
		return 0x80;
	}
	_nop_();_nop_();
	return 0;
}


void ds18b20_write_byte(unsigned char byte) 
{
	unsigned char ii = 0;
	for(ii = 0; ii<8; ++ii) 
	{
		ds18b20_write_bit(byte);
		byte >>= 1;
	}
}
unsigned char ds18b20_read_byte() 
{
	unsigned char ii = 0;
	unsigned char result = 0;
	for(ii = 0; ii<8; ++ii) 
	{
		result >>= 1;
		result |= ds18b20_read_bit();
	}
	return result;
}


void ds18b20_reset() 
{
	DS18B20_OW = 0;//拉低总线
	delay(60);//600us
	DS18B20_OW = 1;//释放总线 等待18B20回应
	while(DS18B20_OW);//等待18B20回应
	while(!DS18B20_OW);//等待18B20释放总线	
}


void DS18B20_Read_Temperature(float* ptr) 
{
	unsigned char temp_L = 0;
	unsigned int temp = 0;
	
	ds18b20_reset();
	ds18b20_write_byte(0xCC);//跳过ROM操作
	ds18b20_write_byte(0x44);//开始转换温度
	delay(5000);
	
	ds18b20_reset();
	ds18b20_write_byte(0xCC);//跳过ROM操作
	ds18b20_write_byte(0xBE);//开始读温度
	temp_L = ds18b20_read_byte();//先读低字节
	temp = ds18b20_read_byte();//再读低字节
	temp = (temp<<8) | temp_L;//将两个字节拼接成16bit
	if(temp & 0x8000) 
	{
		*ptr = ((~temp)+1) * 0.0625f;//零下温度
	} else {
		*ptr = temp * 0.0625f;//零上温度
	}
}

